package com.senlingspace.payment.lakala.service.impl;

import com.alibaba.fastjson2.JSON;
import com.google.common.base.Joiner;
import com.lkl.laop.sdk.LKLSDK;
import com.lkl.laop.sdk.exception.SDKException;
import com.lkl.laop.sdk.request.V3LabsQueryTradequeryRequest;
import com.lkl.laop.sdk.request.V3LabsTransMicropayRequest;
import com.lkl.laop.sdk.request.model.V3LabsTradeLocationInfo;
import com.senlingspace.common.core.dingtalk.DingTalkService;
import com.senlingspace.common.exception.payment.LakalaException;
import com.senlingspace.payment.config.properties.LakalaProperties;
import com.senlingspace.payment.lakala.bean.request.LakalaMicroPayRequest;
import com.senlingspace.payment.lakala.bean.response.LakalaMicroPayResponse;
import com.senlingspace.payment.lakala.bean.response.TradeQueryResponse;
import com.senlingspace.payment.lakala.service.LakalaMicroPayService;
import com.senlingspace.system.domain.SlkjMerchant;
import com.senlingspace.system.mapper.SlkjMerchantMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * 拉卡拉聚合被扫码
 * <p>
 * <a href="https://o.lakala.com/#/home/document/detail?id=112">聚合被扫</a>
 *
 * @author lebronjames
 * @date 2024/07/24
 */
@AllArgsConstructor
@Slf4j
@Service
public class LakalaMicroPayServiceImpl implements LakalaMicroPayService {

    private final LakalaProperties lakalaProperties;
    private final DingTalkService dingTalkService;

    private final SlkjMerchantMapper slkjMerchantMapper;


    @Override
    public LakalaMicroPayResponse microPay(LakalaMicroPayRequest request) throws LakalaException {
        log.info("拉卡拉聚合被扫码，接口入参：{}", JSON.toJSONString(request));
        if (Objects.isNull(request)) {
            log.error("拉卡拉聚合被扫码，支付请求参数为空");
            throw new LakalaException("拉卡拉聚合被扫码，支付请求参数为空");
        }

        if (StringUtils.isBlank(request.getAuthCode())) {
            log.error("拉卡拉聚合被扫码，支付请求参数authCode为空");
            throw new LakalaException("拉卡拉聚合被扫码，支付请求参数authCode为空");
        }

        if (StringUtils.isBlank(request.getOutTradeNo())) {
            log.error("拉卡拉聚合被扫码，支付请求参数outTradeNo为空");
            throw new LakalaException("拉卡拉聚合被扫码，支付请求参数outTradeNo为空");
        }

        if (StringUtils.isBlank(request.getTotalAmount())) {
            log.error("拉卡拉聚合被扫码，支付请求参数totalAmount为空");
            throw new LakalaException("拉卡拉聚合被扫码，支付请求参数totalAmount为空");
        }
        if (request.getTotalAmount().contains(".")) {
            log.error("拉卡拉聚合被扫码，支付金额totalAmount必须转为分");
            throw new LakalaException("拉卡拉聚合被扫码，支付金额totalAmount必须转为分");
        }

        V3LabsTransMicropayRequest sendRequest = buildRequest(request);
        log.info("拉卡拉聚合被扫码支付请求参数：{}", JSON.toJSONString(sendRequest));
        try {
            String json = LKLSDK.httpPost(sendRequest);
            log.info("拉卡拉聚合被扫码支付返回结果：{}", json);
            if (StringUtils.isBlank(json)) {
                log.error("拉卡拉聚合被扫码支付异常，返回结果为空!");
                dingTalkService.sendTextMessage("拉卡拉聚合被扫，支付异常，对应入参：" + JSON.toJSONString(sendRequest), true);
                return null;
            }
            return JSON.parseObject(json, LakalaMicroPayResponse.class);
        } catch (SDKException e) {
            log.error("拉卡拉聚合被扫，支付异常：{}", e.getMessage());
            dingTalkService.sendTextMessage("拉卡拉聚合被扫，支付异常：" + e.getMessage() + "，对应入参：" + JSON.toJSONString(sendRequest), true);
            return null;
        }
    }

    @Override
    public TradeQueryResponse tradeQuery(String outTradeNo, long shopId) throws LakalaException {
        log.info("拉卡拉聚合被扫码，接口入参：{}", outTradeNo);
        if (StringUtils.isBlank(outTradeNo)) {
            log.error("拉卡拉聚合被扫码，支付查询请求参数outTradeNo为空");
            throw new LakalaException("拉卡拉聚合被扫码，支付查询请求参数outTradeNo为空");
        }

        SlkjMerchant merchant = slkjMerchantMapper.selectByShopId(shopId);
        if (Objects.isNull(merchant) || StringUtils.isBlank(merchant.getTermNo()) || StringUtils.isBlank(merchant.getMerchantNo())) {
            log.error("门店 [{}] 商户信息配置有误！", shopId);
            throw new LakalaException("门店商户信息有误！");
        }

        V3LabsQueryTradequeryRequest tradequeryRequest = new V3LabsQueryTradequeryRequest();
        tradequeryRequest.setMerchantNo(merchant.getMerchantNo());
        tradequeryRequest.setTermNo(merchant.getTermNo());
        tradequeryRequest.setOutTradeNo(outTradeNo);
        log.info("拉卡拉聚合被扫码支付查询请求参数：{}", JSON.toJSONString(tradequeryRequest));
        try {
            String json = LKLSDK.httpPost(tradequeryRequest);
            log.info("拉卡拉聚合被扫码支付查询返回结果：{}", json);
            if (StringUtils.isBlank(json)) {
                log.error("拉卡拉聚合被扫码支付查询异常，返回结果为空!");
                dingTalkService.sendTextMessage("拉卡拉聚合被扫码支付查询异常，返回结果为空！" + "，对应入参：outTradeNo=" + outTradeNo, true);
                return null;
            }
            return JSON.parseObject(json, TradeQueryResponse.class);
        } catch (SDKException e) {
            log.error("拉卡拉聚合被扫码支付查询异常：{}", e.getMessage());
            dingTalkService.sendTextMessage("拉卡拉聚合被扫，支付查询异常：" + e.getMessage() + "，对应入参：outTradeNo=" + outTradeNo, true);
            return null;
        }
    }

    private V3LabsTransMicropayRequest buildRequest(LakalaMicroPayRequest request) {
        SlkjMerchant merchant = slkjMerchantMapper.selectByShopId(request.getShopId());
        if (Objects.isNull(merchant) || StringUtils.isBlank(merchant.getTermNo()) || StringUtils.isBlank(merchant.getMerchantNo())) {
            log.error("门店 [{}] 商户信息配置有误！", request.getShopId());
            String logMessage = Joiner.on("").join("门店 [", request.getShopId(), "] 商户信息配置有误，请检查 [slkj_merchant]！");
            dingTalkService.sendTextMessage(logMessage, true);
            throw new LakalaException("支付失败，门店商户信息有误！");
        }

        V3LabsTransMicropayRequest sendRequest = new V3LabsTransMicropayRequest();
        sendRequest.setAuthCode(request.getAuthCode());
        sendRequest.setOutTradeNo(request.getOutTradeNo());
        sendRequest.setTotalAmount(request.getTotalAmount());// TODO 切记: 单位=分
        sendRequest.setRemark(request.getRemark());
        sendRequest.setSubject(request.getSubject());
        sendRequest.setMerchantNo(merchant.getMerchantNo());
        sendRequest.setTermNo(merchant.getTermNo());
        sendRequest.setLocationInfo(new V3LabsTradeLocationInfo(lakalaProperties.getServerIpAddress()));
        return sendRequest;
    }

}
